package com.zwh.modules.hzlog.service;

import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.metadata.Sheet;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.zwh.common.codec.EncodeUtils;
import com.zwh.modules.hzlog.controller.TestController;
import com.zwh.modules.hzlog.entity.WeatherModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 *
 * @author doubleZhang
 */
public  class AutoParagrapExportExcel {
    Logger logger= LoggerFactory.getLogger(AutoParagrapExportExcel.class);

    //默认设置为最大100万条数据
    static int customSheetMaxDataSize=1000000;

    public void testExportForDivide(HttpServletRequest request, HttpServletResponse response){
        logger.info("分页分批查询导出数据导出开始");
        String fileName="用户洞察中心App报表.xlsx";
        String sheetName="用户洞察中心App报表";
        try {
            response.reset();
            response.setContentType("application/octet-stream; charset=utf-8");
            response.setHeader("Content-Disposition", "attachment; filename="+ EncodeUtils.encodeUrl(fileName));
            OutputStream out = response.getOutputStream();

            //这里指定需要表头，因为model通常包含表信头息
            ExcelWriter writer = new ExcelWriter(out, ExcelTypeEnum.XLSX, true);
            //写第一个sheet,数据全是List<String> 无模型映射关系
            int sheetNo=1;
            Sheet sheet = new Sheet(1, 0, WeatherModel.class);
            //设置自适应宽度
            sheet.setAutoWidth(Boolean.TRUE);
            //设置表格样式
            //设置sheetName
            sheet.setSheetName(sheetName);
            int pageSize = 50000; // 分5千条一次查询
            int dataLength = 2000001; //假设数据总量为十万条数据
            //一百万数据存储一个sheet
            int remainNumber=dataLength%customSheetMaxDataSize;
            int sheetNoSize=dataLength/customSheetMaxDataSize;
            if(remainNumber!=0){
                sheetNoSize++;
            }

            List<WeatherModel> resultList = null;
            Map<String, Object> condition = new HashMap<>();
            boolean isFirst=true;
            int startIndex=0;
            while(sheetNo<=sheetNoSize){
                if(isFirst){
                    isFirst=false;
                }else{
                    //sheet指向下一个sheet
                    sheet = new Sheet(sheetNo, 0, WeatherModel.class);
                    sheet.setSheetName(sheetName+sheetNo);
                }

                // 要保证每个sheet页总数据最多为100万条数据
                int sheetMaxDataSize=customSheetMaxDataSize;
                // 如果剩余数量不足100万条,设置当前sheet也数据大小为剩余数据大小
                if(sheetNo*sheetMaxDataSize>dataLength){
                    sheetMaxDataSize=dataLength-((sheetNo-1)*sheetMaxDataSize);
                }
                //开始下标，到结束下标
                while(true){
                    int curDataSize=pageSize;
                    //遍历到当前sheet的行数是否大于最大sheet行数限制
                    int currentSheetRow=startIndex-(sheetNo-1)*customSheetMaxDataSize;
                    if(currentSheetRow+pageSize>sheetMaxDataSize){
                        //当前sheet超过100万条数据,到下一个sheet页
                        //获取当前要查询的总数据
                        curDataSize=sheetMaxDataSize-currentSheetRow;
                        condition.put("startIndex", startIndex);
                        condition.put("pageSize", curDataSize);
                        if(curDataSize==0){
                            break;
                        }
                        //查询指定位置数据列表
                        resultList = queryList(condition);
                        if (resultList == null || resultList.isEmpty()) {
                            //写数据
                            writer.write(resultList, sheet);
                            break;
                        }
                        //当前sheet最后一次写入数据
                        writer.write(resultList, sheet);
                        //设置当前下标为sheetNo的第一条数据
                        startIndex=sheetNo*customSheetMaxDataSize;
                        break;
                    }

                    //当前sheet表可以写入查询数据大小
                    condition.put("startIndex", startIndex);
                    condition.put("pageSize", curDataSize);
                    resultList = queryList(condition);
                    if (resultList == null || resultList.isEmpty()) {
                        //写数据
                        writer.write(resultList, sheet);
                        break;
                    }
                    startIndex=startIndex+curDataSize;

                    writer.write(resultList, sheet);
                }

                //查询数据为空时，结束循环
                if (resultList == null || resultList.isEmpty()) {
                    break;
                }
                sheetNo++;
            }
            //关闭writer的输出流
            writer.finish();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    public List<WeatherModel> queryList(Map<String, Object> condition) {
        List<WeatherModel> list = new ArrayList<>();
        Integer startIndex = (Integer) condition.get("startIndex");
        Integer pageSize =  (Integer)condition.get("pageSize");
        int endIndex=startIndex+pageSize;
        while(startIndex<endIndex){
            WeatherModel item =new WeatherModel();
            item.setAreaId("areaid"+startIndex);
            item.setNameCn("name"+startIndex);
            item.setNameCn("中文"+startIndex);
            list.add(item);
            startIndex++;
        }
        return list;
    }
}
